package com.gss.stockLedger.service;

import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.Stack;

import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.gss.stockLedger.dao.QueryStockNoDaoSupportDAO;
import com.gss.stockLedger.domain.FIFOReportDTO;
import com.gss.stockLedger.form.ReportGenerateForm;

@Service
public class WACReportGenerationThreadedService {

	Logger logger = Logger.getLogger(getClass());
	
	@Autowired
	QueryStockNoDaoSupportDAO queryStockNoDaoSupportDAO;
	
	public static Set<String> Consumption_Transaction_Type = new HashSet<String>();
	public int sheetCounter=0;
	static {
		Consumption_Transaction_Type.add("CONS");
		Consumption_Transaction_Type.add("FOC");
		Consumption_Transaction_Type.add("RTV");
		Consumption_Transaction_Type.add("SCRAP");
		Consumption_Transaction_Type.add("CAPTIVE");
		Consumption_Transaction_Type.add("SALES");
		
	}
	
	public boolean generateWACReport(ReportGenerateForm reportForm, Date date) {
		logger.debug("entered WAC");
		boolean resultOfSucess = false;
		GenerateExcelThread generateExcelThread = null;
		
		WacDataProcessorThread dataProcessorThread = null;
		long startTime = System.currentTimeMillis();
	try{
	
		List<FIFOReportDTO> finalReportList;

		List<Object[]> partIdList = queryStockNoDaoSupportDAO.getUniquePartIds(reportForm.getInvType(),reportForm.getLastPartId(),reportForm.getCompanyName());
		logger.debug("Size of partId list: " + partIdList.size());
		LinkedList<FIFOReportDTO> transactionQ = null;
		Stack<FIFOReportDTO> consumedStack = null;
		LinkedList<FIFOReportDTO> transactionQForReport = null;
//		System.out.println(partIdList.size());
		
		String sheetName = reportForm.getReportCategory() + reportForm.getReportType();				//added by ashish
		Workbook workbook = ExcelCreationService.createExcelFile(sheetName,reportForm.getValuationMethod(),reportForm.getStartDate(),
				reportForm.getEndDate(),date,reportForm.getReportCategory(),reportForm.getReportType(),reportForm.getInvType(), reportForm.getCompanyName());			//added by ashish
		logger.debug("default excel workbook created");			//added by ashish
		
		//create excel thread
		generateExcelThread = new GenerateExcelThread(workbook, reportForm, date);
		generateExcelThread.setRunning(true);
		
		generateExcelThread.start();
		
		int partIdCounter = 0;
		int totalPartIds = partIdList.size();
		
		ThreadCounter threadCounter = new ThreadCounter();
		threadCounter.setNumberOfThreads(0);
		
		for (Object[] object : partIdList) {
			//implementing multiple threads
			while(threadCounter.getNumberOfThreads() >= 25){
				Thread.sleep(1000l);
			}
			
			dataProcessorThread = new WacDataProcessorThread(generateExcelThread, object, queryStockNoDaoSupportDAO, reportForm, threadCounter);
			
			Thread thread = new Thread(dataProcessorThread);
			thread.start();
			threadCounter.setNumberOfThreads(1);
			System.out.println("Processing: " + ++partIdCounter + " of " + totalPartIds + " ++++Part Id: " + object[0].toString() + " +++Inv. Type: " + object[1].toString());
		}
		while(threadCounter.getNumberOfThreads() >0){
			System.out.println("Waiting for threads to finish: " + threadCounter.getNumberOfThreads());
			Thread.sleep(1000l);
		}
		resultOfSucess = true;
		while(generateExcelThread.getPartId_data_map().size() > 0){
			Thread.sleep(2000l);
			System.out.println("Entries left: " + generateExcelThread.getPartId_data_map().size());
		}
		generateExcelThread.setRunning(false);
		generateExcelThread.join();
		System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%  STILL WRITING  %%%%%%%%%%%%%%%%%%%%%%%%%%");
		
	}
	catch (Throwable e) {
		e.printStackTrace();
	}
	finally{
		if(null != generateExcelThread){
			generateExcelThread.setRunning(false);
		}
		System.out.println("time taken: " + (System.currentTimeMillis() - startTime));
	}
	return resultOfSucess;
	}
}
